import { useEffect, useState, Key, FC } from 'react';

import TableRender from '@/biz-components/table-render';

import { getPageMeta } from '@/services/request/meta';
import { useInitData } from '@/biz-components/hoc-form/with-list/use-events';
import { PageConfig } from '@/components/schema-form-render/meta';
import { DynamicObjectAny } from '@/typings';
import { getTempData } from '@/biz-components/_common/wrapXhr';
import { toArray } from '@/biz-components/_common/util';

export interface SelectionTableProps {
  value?: any[];
  onChange?: (value: any[]) => void;
  api?: {
    type: string;
    url: string;
    params: DynamicObjectAny;
  };
  rowKey?: string;
  pageCode: string;
  rowSelectionType: string;
  editable?: boolean;
}

const SelectionTable: FC<SelectionTableProps> = (props) => {
  const { value, onChange, api, rowKey, pageCode, rowSelectionType, editable } = props;
  const [remoteMetasConfig, setRemoteMetasConfig] = useState<PageConfig>({
    labelAlign: 'right',
    layout: 3,
    pageDatas: [],
  });

  const [loading, setLoading] = useState(false);

  const [dataSource, setDataSource] = useState([]);

  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);

  const [selectValue, setSelectValue] = useState<any[]>([]);

  const { tableColumns, tableButtons } = useInitData(undefined, remoteMetasConfig);

  const key = rowKey || 'id';

  const baseRowSelection = {
    type: rowSelectionType,
    selectedRowKeys,
    onChange: (rowKeys: Key[], selectedRows: any[]) => {
      const allDataSourceKey = dataSource?.map((item) => item[key]) || [];
      setSelectValue(
        selectedRows
          .concat(
            selectValue.filter((item: any) => {
              return !selectedRows.find((current) => current[key] === item[key]);
            }),
          )
          .filter((val) => val),
      );
      const mapValue = (value || [])
        .map((item: any) => {
          return selectValue.find((current) => current[key] === item[key]);
        })
        .filter((val: any) => val);

      const changeValue = mapValue
        .filter((item: any) => !allDataSourceKey.includes(item[key]))
        .concat(selectedRows.filter((item) => allDataSourceKey.includes(item[key])));

      setSelectedRowKeys(changeValue.map((item: any) => item[key]));

      onChange?.(changeValue);
    },
  };

  // 获取 metasConfig
  useEffect(() => {
    if (pageCode) {
      getPageMeta(pageCode || '').then((res: any) => {
        if (res.success) {
          setRemoteMetasConfig(res.result);
        }
      });
    }
  }, [pageCode]);

  useEffect(() => {
    const { url } = api || {};
    setDataSource([]);

    if (url && editable) {
      setLoading(true);
      getTempData(api)
        .then((result: any) => {
          setLoading(false);
          setDataSource(result);
        })
        .catch((err) => {
          setLoading(false);
        });
    }
  }, [api, editable]);

  useEffect(() => {
    setSelectedRowKeys(value?.map((item) => item[key]) || []);
    setSelectValue(value || []);
  }, [value]);

  return editable ? (
    <>
      <TableRender
        rowKey={key}
        metas={tableColumns || []}
        rowSelection={baseRowSelection}
        isRequesting={loading}
        operAuths={tableButtons?.map(() => '')}
        dataSource={dataSource}
        pagination={false}
      />
    </>
  ) : (
    <TableRender
      rowKey={key}
      metas={tableColumns || []}
      isRequesting={loading}
      operAuths={tableButtons?.map(() => '')}
      dataSource={toArray(value)}
      pagination={false}
    />
  );
};

SelectionTable.defaultProps = {
  rowKey: 'id',
  rowSelectionType: 'checkbox',
  editable: true,
};

export default SelectionTable;
